package com.ds.esd.bpm.worklist;


import com.ds.bpm.client.ActivityInst;
import com.ds.bpm.client.ActivityInstHistory;
import com.ds.bpm.client.ProcessDefVersion;
import com.ds.bpm.client.ProcessInst;
import com.ds.bpm.client.data.SearchData;
import com.ds.bpm.engine.BPMException;
import com.ds.bpm.engine.WorkflowClientService;
import com.ds.bpm.engine.query.BPMCondition;
import com.ds.bpm.engine.query.BPMConditionKey;
import com.ds.bpm.enums.activityinst.ActivityInstDealMethod;
import com.ds.bpm.enums.activityinst.ActivityInstRunStatus;
import com.ds.bpm.enums.activityinst.ActivityInstStatus;
import com.ds.bpm.enums.process.ProcessDefVersionStatus;
import com.ds.bpm.enums.process.ProcessInstStatus;
import com.ds.bpm.enums.right.RightConditionEnums;
import com.ds.common.JDSException;
import com.ds.common.query.JoinOperator;
import com.ds.common.query.Operator;
import com.ds.common.query.Order;
import com.ds.config.ErrorListResultModel;
import com.ds.config.ListResultModel;
import com.ds.context.JDSActionContext;
import com.ds.enums.db.MethodChinaName;
import com.ds.esd.bpm.worklist.view.ActivityInstListView;
import com.ds.esd.bpm.worklist.view.NotStartInstListView;
import com.ds.esd.bpm.worklist.view.ProcessDefVersionView;
import com.ds.esd.bpm.worklist.view.ProcessInstListView;
import com.ds.esd.client.ESDFacrory;
import com.ds.esd.client.Project;
import com.ds.esd.custom.annotation.CustomAnnotation;
import com.ds.esd.custom.annotation.GridViewAnnotation;
import com.ds.esd.custom.annotation.TreeAnnotation;
import com.ds.esd.custom.buttonviews.annotation.ButtonViewsAnnotation;
import com.ds.esd.custom.module.annotation.ModuleAnnotation;
import com.ds.esd.dsm.domain.annotation.BpmDomain;
import com.ds.esd.dsm.domain.enums.BpmDomainType;
import com.ds.esd.tool.ui.component.tab.SideBarStatusType;
import com.ds.esd.tool.ui.enums.BarLocationType;
import com.ds.jds.core.esb.EsbUtil;
import com.ds.server.JDSClientService;
import com.ds.server.JDSServer;
import com.ds.web.annotation.Aggregation;
import com.ds.web.annotation.AggregationType;
import com.ds.web.util.PageUtil;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.List;

@Controller
@RequestMapping("/bpm/worklist/")
@MethodChinaName(cname = "工作流列表", imageClass = "bpmfont bpmgongzuoliuzhutiguizeweihuguanli")
@BpmDomain(type = BpmDomainType.worklist)
@Aggregation(type = AggregationType.customDomain, rootClass = WorkListService.class)
@ButtonViewsAnnotation(barLocation = BarLocationType.left, sideBarStatus = SideBarStatusType.fold, barSize = "16em", noFoldBar = true)
@TreeAnnotation
public class WorkListService {


    @MethodChinaName(cname = "流程定义列表")
    @RequestMapping(method = RequestMethod.POST, value = "ProcessDefVersionList")
    @GridViewAnnotation(editorPath = "NewProcess")
    @ModuleAnnotation(imageClass = "bpmfont bpmgongzuoliuzhutiguizeweihuguanli", caption = "流程定义列表")
    public @ResponseBody
    ListResultModel<List<ProcessDefVersionView>> getProcessDefVersionList(String projectName) {
        ListResultModel result = new ListResultModel();
        try {
            BPMCondition condition = new BPMCondition(BPMConditionKey.PROCESSDEF_VERSION_PUBLICATIONSTATUS, Operator.EQUALS, ProcessDefVersionStatus.RELEASED.getType());
            BPMCondition sysCondition = new BPMCondition(BPMConditionKey.PROCESSDEF_VERSION_PROCESSDEF_ID, Operator.IN, "SELECT PROCESSDEF_ID FROM BPM_PROCESSDEF WHERE SYSTEMCODE='" + ESDFacrory.getESDClient().getSystemCode() + "'");
            condition.addCondition(sysCondition, JoinOperator.JOIN_AND);
            if (projectName != null && !projectName.equals("")) {
                Project project = ESDFacrory.getESDClient().getProjectByName(projectName);
                BPMCondition projectCondition = new BPMCondition(BPMConditionKey.PROCESSDEF_VERSION_PROCESSDEF_ID, Operator.IN, "SELECT PROCESSDEF_ID FROM BPM_PROCESSDEF WHERE CLASSIFICATION='" + project.getProjectName() + "'");
                condition.addCondition(projectCondition, JoinOperator.JOIN_AND);
            }
            ListResultModel<List<ProcessDefVersion>> versionList = getClient().getProcessDefVersionList(condition, null, null);
            result = PageUtil.changPageList(versionList, ProcessDefVersionView.class);
        } catch (Exception e) {
            result = new ErrorListResultModel();
            ((ErrorListResultModel<List<ProcessInstListView>>) result).setErrdes(e.getMessage());
            e.printStackTrace();
        }
        return result;
    }


    @MethodChinaName(cname = "草稿箱")
    @RequestMapping(method = RequestMethod.POST, value = "NotStartActivityInstList")
    @GridViewAnnotation
    @ModuleAnnotation(imageClass = "bpmfont bpmgongzuoliu", caption = "草稿箱")
    public @ResponseBody
    ListResultModel<List<NotStartInstListView>> getNotStartActivityInstList(@RequestBody SearchData data) {
        ListResultModel<List<NotStartInstListView>> result = new ListResultModel<List<NotStartInstListView>>();
        data.setConditionEnums(RightConditionEnums.CONDITION_CURRENTWORK_NOTSTART);
        result = searchActivityInst(data, NotStartInstListView.class);
        return result;

    }


    @MethodChinaName(cname = "最新待办")
    @RequestMapping(method = RequestMethod.POST, value = "WaitedActivityInstList")
    @GridViewAnnotation
    @ModuleAnnotation(imageClass = "bpmfont bpmyuxiandengjibanli", caption = "最新待办")
    public @ResponseBody
    ListResultModel<List<ActivityInstListView>> getWaitedActivityInstList(@RequestBody SearchData data) {
        ListResultModel<List<ActivityInstListView>> result = new ListResultModel<List<ActivityInstListView>>();
        data.setConditionEnums(RightConditionEnums.CONDITION_WAITEDWORK);
        result = searchActivityInst(data, ActivityInstListView.class);
        return result;
    }


    @MethodChinaName(cname = "所有在办")
    @RequestMapping(method = RequestMethod.POST, value = "MyActivityInstList")
    @GridViewAnnotation
    @ModuleAnnotation(imageClass = "bpmfont bpmdingzhigongzuoliu", caption = "所有在办")
    public @ResponseBody
    ListResultModel<List<ActivityInstListView>> getMyActivityInstList(@RequestBody SearchData data) {
        ListResultModel<List<ActivityInstListView>> result = new ListResultModel<List<ActivityInstListView>>();
        data.setConditionEnums(RightConditionEnums.CONDITION_MYWORKNOTREAD);
        result = searchActivityInst(data, ActivityInstListView.class);
        return result;

    }


    @MethodChinaName(cname = "已办理")
    @RequestMapping(method = RequestMethod.POST, value = "CompletedActivityInstList")
    @GridViewAnnotation
    @ModuleAnnotation(imageClass = "bpmfont bpmshujukaifagongzuoliushujutansuozuijindakai", caption = "已办理")
    public @ResponseBody
    ListResultModel<List<ActivityInstListView>> getCompletedActivityInstList(@RequestBody SearchData data) {
        ListResultModel<List<ActivityInstListView>> result = new ListResultModel<List<ActivityInstListView>>();
        data.setConditionEnums(RightConditionEnums.CONDITION_COMPLETEDWORK);
        result = searchActivityInst(data, ActivityInstListView.class);
        return result;

    }

    @MethodChinaName(cname = "归档文件")
    @GridViewAnnotation
    @ModuleAnnotation(imageClass = "bpmfont bpmlishihistory2", caption = "归档文件")
    @RequestMapping(method = RequestMethod.POST, value = "CompletedProcessInstList")
    public @ResponseBody
    ListResultModel<List<ProcessInstListView>> getCompletedProcessInstList(@RequestBody SearchData data) {
        ListResultModel<List<ProcessInstListView>> result = new ListResultModel<List<ProcessInstListView>>();
        try {
            BPMCondition condition = new BPMCondition(BPMConditionKey.PROCESSINST_STATE,
                    Operator.EQUALS, ProcessInstStatus.completed);
            ListResultModel<List<ProcessInst>> processList = getClient().getProcessInstList(condition, RightConditionEnums.CONDITION_COMPLETEDWORK, null, null);
            result = PageUtil.changPageList(processList, ProcessInstListView.class);
        } catch (BPMException e) {
            result = new ErrorListResultModel();
            ((ErrorListResultModel<List<ProcessInstListView>>) result).setErrdes(e.getMessage());
            ((ErrorListResultModel<List<ProcessInstListView>>) result).setErrcode(e.getErrorCode());
            e.printStackTrace();
        }

        return result;

    }


    @MethodChinaName(cname = "阅办工作实例")
    @RequestMapping(method = RequestMethod.POST, value = "ReadActivityInstList")
    @GridViewAnnotation
    @ModuleAnnotation(imageClass = "bpmfont bpmyuedu", caption = "阅办工作实例")
    public @ResponseBody
    ListResultModel<List<ActivityInstListView>> getReadActivityInstList(@RequestBody SearchData data) {
        ListResultModel<List<ActivityInstListView>> result = new ListResultModel<List<ActivityInstListView>>();
        data.setConditionEnums(RightConditionEnums.CONDITION_READ);
        result = searchActivityInst(data, ActivityInstListView.class);
        return result;

    }

    @MethodChinaName(cname = "阅闭工作实例")
    @RequestMapping(method = RequestMethod.POST, value = "EndReadActivityInstList")
    @CustomAnnotation(imageClass = "bpmfont bpmshouhui")
    @GridViewAnnotation
    @ModuleAnnotation(imageClass = "bpmfont bpmshouhui", caption = "阅闭工作实例")
    public @ResponseBody
    ListResultModel<List<ActivityInstListView>> getEndReadActivityInstList(@RequestBody SearchData data) {
        ListResultModel<List<ActivityInstListView>> result = new ListResultModel<List<ActivityInstListView>>();
        data.setConditionEnums(RightConditionEnums.CONDITION_ENDREAD);
        result = searchActivityInst(data, ActivityInstListView.class);
        return result;

    }


    @MethodChinaName(cname = "条件检索")
    @RequestMapping(method = RequestMethod.POST, value = "searchActivityInst")
    public @ResponseBody
    <T> ListResultModel<List<T>> searchActivityInst(@RequestBody SearchData data, Class<T> clazz) {
        ListResultModel<List<T>> result = new ListResultModel<List<T>>();
        BPMCondition condition = null;
        RightConditionEnums conditionEnums = data.getConditionEnums();
        String processDefId = data.getProcessDefId();
        if (conditionEnums == null) {
            conditionEnums = RightConditionEnums.CONDITION_WAITEDWORK;
        }
        switch (conditionEnums) {
            case CONDITION_WAITEDWORK:
                condition = new BPMCondition(BPMConditionKey.ACTIVITYINST_STATE,
                        Operator.EQUALS, ActivityInstStatus.notStarted);
                break;
            case CONDITION_CURRENTWORK_NOTSTART:
                condition = new BPMCondition(BPMConditionKey.ACTIVITYINST_RUNSTATUS,
                        Operator.EQUALS, ActivityInstRunStatus.PROCESSNOTSTARTED);
                break;
            case CONDITION_CURRENTWORK:
                condition = new BPMCondition(BPMConditionKey.ACTIVITYINST_STATE,
                        Operator.EQUALS, ActivityInstStatus.running);
                break;
            case CONDITION_READ:
                condition = new BPMCondition(BPMConditionKey.ACTIVITYINST_STATE,
                        Operator.EQUALS, ActivityInstStatus.READ);
                break;

            case CONDITION_ENDREAD:
                condition = new BPMCondition(BPMConditionKey.ACTIVITYINST_STATE,
                        Operator.EQUALS, ActivityInstStatus.ENDREAD);

                break;
            default:
                condition = new BPMCondition(BPMConditionKey.ACTIVITYINST_STATE,
                        Operator.NOT_EQUAL, ActivityInstStatus.aborted);

                break;
        }


        if (processDefId != null) {
            BPMCondition ccondition = new BPMCondition(BPMConditionKey.ACTIVITYINST_PROCESSDEF_ID, Operator.EQUALS, processDefId);
            condition.addCondition(ccondition, JoinOperator.JOIN_AND);
        }


        if (data.getStartTime() != null && data.getStartTime() != 0) {
            BPMCondition startcondition = new BPMCondition(BPMConditionKey.ACTIVITYINST_ARRIVEDTIME,
                    Operator.GREATER_THAN, data.getStartTime());
            condition.addCondition(startcondition, JoinOperator.JOIN_AND);
        }

        if (data.getEndTime() != null && data.getEndTime() != 0) {
            BPMCondition endcondition = new BPMCondition(BPMConditionKey.ACTIVITYINST_ARRIVEDTIME,
                    Operator.LESS_THAN, data.getEndTime());
            condition.addCondition(endcondition, JoinOperator.JOIN_AND);
        }
        if (data.getTitle() != null && !data.getTitle().equals("")) {
            BPMCondition endcondition = new BPMCondition(BPMConditionKey.ACTIVITYINST_PROCESSINST_ID,
                    Operator.IN, "select PROCESSINST_ID from BPM_PROCESSINSTANCE where " + BPMConditionKey.PROCESSINST_NAME + " like '%" + data.getTitle() + "%'");
            condition.addCondition(endcondition, JoinOperator.JOIN_AND);
        }
        String projectId = data.getProjectId();
        try {
            if (projectId != null && !projectId.equals("")) {
                Project project = ESDFacrory.getESDClient().getProjectById(projectId);
                BPMCondition projectCondition = new BPMCondition(BPMConditionKey.ACTIVITYINST_PROCESSDEF_ID, Operator.IN, "SELECT PROCESSDEF_ID FROM BPM_PROCESSDEF WHERE CLASSIFICATION='" + project.getProjectName() + "'");
                condition.addCondition(projectCondition, JoinOperator.JOIN_AND);
            } else {
                BPMCondition sysCondition = new BPMCondition(BPMConditionKey.ACTIVITYINST_PROCESSDEF_ID, Operator.IN, "SELECT PROCESSDEF_ID FROM BPM_PROCESSDEF WHERE SYSTEMCODE='" + ESDFacrory.getESDClient().getSystemCode() + "'");
                condition.addCondition(sysCondition, JoinOperator.JOIN_AND);
            }
        } catch (JDSException e) {
            e.printStackTrace();
        }

        condition.addOrderBy(new Order(BPMConditionKey.ACTIVITYINST_ARRIVEDTIME, false));
        try {
            ListResultModel<List<ActivityInst>> activityInstList = getClient().getActivityInstList(condition, conditionEnums, null, null);
            result = PageUtil.changPageList(activityInstList, clazz);
        } catch (BPMException e) {
            result = new ErrorListResultModel();
            ((ErrorListResultModel<List<T>>) result).setErrdes(e.getMessage());
            ((ErrorListResultModel<List<T>>) result).setErrcode(e.getErrorCode());
            e.printStackTrace();
        }

        return result;


    }

    @MethodChinaName(cname = "条件检索")
    @RequestMapping(method = RequestMethod.POST, value = "searchActivityHistory")
    @GridViewAnnotation
    public @ResponseBody
    ListResultModel<List<ActivityInstListView>> searchActivityHistory(@RequestBody SearchData data) {
        ListResultModel<List<ActivityInstListView>> result = new ListResultModel<List<ActivityInstListView>>();
        BPMCondition condition = null;
        RightConditionEnums conditionEnums = data.getConditionEnums();
        String processDefId = data.getProcessDefId();
        if (conditionEnums == null) {
            conditionEnums = RightConditionEnums.CONDITION_WAITEDWORK;
        }

        condition = new BPMCondition(BPMConditionKey.ACTIVITYHISTORY_DEALMETHOD,
                Operator.EQUALS, ActivityInstDealMethod.DEALMETHOD_NORMAL);


        if (processDefId != null) {
            BPMCondition ccondition = new BPMCondition(BPMConditionKey.ACTIVITYHISTORY_PROCESSDEF_ID, Operator.EQUALS, processDefId);
            condition.addCondition(ccondition, JoinOperator.JOIN_AND);
        }


        if (data.getEndTime() != null && data.getEndTime() != 0) {
            BPMCondition endcondition = new BPMCondition(BPMConditionKey.ACTIVITYHISTORY_ARRIVEDTIME,
                    Operator.LESS_THAN, data.getEndTime());
            condition.addCondition(endcondition, JoinOperator.JOIN_AND);
        }
        if (data.getTitle() != null && !data.getTitle().equals("")) {
            BPMCondition endcondition = new BPMCondition(BPMConditionKey.ACTIVITYHISTORY_PROCESSINST_ID,
                    Operator.IN, "select PROCESSINST_ID from BPM_PROCESSINSTANCE where " + BPMConditionKey.PROCESSINST_NAME + " like '%" + data.getTitle() + "%'");
            condition.addCondition(endcondition, JoinOperator.JOIN_AND);
        }


        condition.addOrderBy(new Order(BPMConditionKey.ACTIVITYHISTORY_ARRIVEDTIME, false));
        try {
            ListResultModel<List<ActivityInstHistory>> activityInstList = getClient().getActivityInstHistoryList(condition, conditionEnums, null, null);
            result = PageUtil.changPageList(activityInstList, ActivityInstListView.class);
        } catch (BPMException e) {
            result = new ErrorListResultModel();
            ((ErrorListResultModel<List<ActivityInstListView>>) result).setErrdes(e.getMessage());
            ((ErrorListResultModel<List<ActivityInstListView>>) result).setErrcode(e.getErrorCode());
            e.printStackTrace();
        }

        return result;


    }


    /**
     * @return
     */
    private WorkflowClientService getClient() {
        JDSClientService service = JDSActionContext.getActionContext().Par(JDSClientService.class);
        if (service == null) {
            try {
                JDSActionContext.getActionContext().getSession().put("JDSUSERID", JDSServer.getInstance().getAdminUser().getId());
            } catch (JDSException e) {
                e.printStackTrace();
            }
        }
        WorkflowClientService client = EsbUtil.parExpression("$BPMC", WorkflowClientService.class);
        return client;
    }
}
